package com.dyh.quickdemozwei.daqs;

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @Author: yhdong
 * @Date: 2021/9/30 16:36
 */
@Slf4j
public class BizParallel  {
    Map<String,DyhCountSynchronizer> code2Synchronizer = new HashMap<>();

    {
        code2Synchronizer.put("shop1",new DyhCountSynchronizer(2));
        code2Synchronizer.put("shop2",new DyhCountSynchronizer(1));
    }

    ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
            3,3,120, TimeUnit.SECONDS,new SynchronousQueue<>(),
            new ThreadFactoryBuilder().setNameFormat("BizParallel"+"-%d").build(),
            new ThreadPoolExecutor.AbortPolicy()

    );

    /*
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(1, 4, 180, TimeUnit.SECONDS, queue,
                r -> new Thread(r,"PicAutoMatchPool"+"-"+r.hashCode()),
                new ThreadPoolExecutor.CallerRunsPolicy()
                );
    */

    @Test
    public void test(){
        /*7*/
        List<DemoTask> tasks = Lists.newArrayList(
                new DemoTask("shop1"),
                new DemoTask("shop2"),
                new DemoTask("shop1"),
                new DemoTask("shop2"),
                new DemoTask("shop1"),
                new DemoTask("shop1"),
                new DemoTask("shop1")
        );
        runTasks(tasks);
        //runTasksBefore(tasks);
    }


    @SneakyThrows
    public void runTasksBefore(List<DemoTask> tasks) {
        for (DemoTask task : tasks) {
          poolExecutor.submit(()->runOneTask(task));
          //get阻塞在这里就不会
        }
    }

    @SneakyThrows
    public void runTasks(List<DemoTask> tasks){
        for (DemoTask task : tasks) {
           DyhCountSynchronizer synchronizer = code2Synchronizer.get(task.getShopNick());
           synchronizer.acquire(1);
           poolExecutor.submit(()->runOneTask(task,synchronizer));
        }

//       Map<String,List<DemoTask>> groupTasks =
//               tasks.stream().collect(Collectors.groupingBy(DemoTask::getShopNick));
//
//        for (Map.Entry<String, List<DemoTask>> entry : groupTasks.entrySet()) {
//            List<DemoTask> taskInGroup =  entry.getValue();
//            for (DemoTask demoTask : taskInGroup) {
//                DyhCountSynchronizer synchronizer = code2Synchronizer.get(entry.getKey());
//                synchronizer.acquire(1);
//                poolExecutor.submit(()->runTasks());
//            }
//        }
    }


    @SneakyThrows
    void runOneTask(DemoTask task, DyhCountSynchronizer synchronizer)   {
        log.info("{} {} {}开始",Thread.currentThread().getName(),task.getShopNick(),synchronizer.getCount());
        Thread.sleep(30000);
        log.info("{} {} 结束",Thread.currentThread().getName(),task.getShopNick());
        synchronizer.release(1);
    }

    @SneakyThrows
    void runOneTask(DemoTask task)   {
        log.info("{} {} 开始",Thread.currentThread().getName(),task.getShopNick());
        Thread.sleep(2000);
        log.info("{} {} 结束",Thread.currentThread().getName(),task.getShopNick());
    }
}
